package com.dd.stack.jvm.string;

import java.lang.reflect.Field;

/**
 * @Author liuxianmeng
 * @CreateTime 2025/9/8 22:19
 * @Description 类功能作用说明
 */
public class StringPrinciple {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        //StringPrinciple.m1();
        //StringPrinciple.m2();
        //StringPrinciple.m3();
        //StringPrinciple.m4();
        StringPrinciple.analyzeMemoryUsage();
        StringPrinciple.explainStringPool();
    }
    public static void m1() {
        String s1 = "a";
        String s2 = "b";
        String s3 = "ab";
        String s4 = s1 + s2;
        System.out.println(s3 == s4);
        StringPrinciple stringPrinciple = new StringPrinciple();
        stringPrinciple.toString().intern();
        System.out.println("############################################");
        String str1 = new String("QQQ");
        String str2 = new String("WWW");
        String str3 = str1 + str2;
        String str4 = new String("QQQWWW");
        System.out.println("str4 hash = " + str4.hashCode()); // -1898701402
        String str5 = str3.intern();
        String str6 = "QQQWWW";
        System.out.println("str1 hash = " + str1.hashCode());
        System.out.println("str2 hash = " + str2.hashCode());
        System.out.println("str3 hash = " + str3.hashCode());
        System.out.println("str4 hash = " + str4.hashCode());
        System.out.println("str5 hash = " + str5.hashCode());
        System.out.println("str6 hash = " + str6.hashCode());
        System.out.println(str3 == str4); // false
        System.out.println(str3 == str5); // false
        System.out.println(str4 == str3); // false
        System.out.println(str4 == str5); // false
        System.out.println(str5 == str6); // true
        System.out.println(str1.intern() == "QQQ"); // true
        System.out.println(str2.intern() == "WWW"); // true
    }

    public static void m2() {
        String str = new String("Q") + new String("W");
        String str2 = str.intern();
        System.out.println(str == str2);
        System.out.println(str == "QW");
        System.out.println(str2 == "QW");
    }

    public static void m3() throws NoSuchFieldException, IllegalAccessException {
        String str = new String("Q") + new String("W");
        String str2 = str.intern();
        String str3 = "QW"; // !!! 这个字面量的出现会决定反射修改后的字面量不会创建新的字符串对象 而是复用str对象

        // 修改str内部的char数组（通过反射）
        Field valueField = String.class.getDeclaredField("value");
        valueField.setAccessible(true);
        char[] value = (char[]) valueField.get(str);
        value[1] = 'X';  // 将'W'改为'X'

        System.out.println(str);     // 输出"QX"
        System.out.println(str2);    // 输出"QX"
        //System.out.println(str3);    // 输出"QX"
        System.out.println("QW");    // 输出"QX"
        String str4 = "QW";
        System.out.println(str4);

        // 检查引用是否相同
        System.out.println(str == "QW");      // 输出false
        System.out.println(str2 == "QW");     // 输出false
    }

    public static void m4() throws NoSuchFieldException, IllegalAccessException {
        String str = new String("Q") + new String("W");
        String str2 = str.intern();

        Field valueField = String.class.getDeclaredField("value");
        valueField.setAccessible(true);
        char[] value = (char[]) valueField.get(str);
        value[1] = 'X';

        System.out.println("str: " + str + " @ " + System.identityHashCode(str));
        System.out.println("str2: " + str2 + " @ " + System.identityHashCode(str2));
        // 新建一个字符串对象
        System.out.println("\"QW\": " + "QW" + " @ " + System.identityHashCode("QW"));

        System.out.println("str == \"QW\": " + (str == "QW"));      // false
        System.out.println("str2 == \"QW\": " + (str2 == "QW"));   // false
    }

    /* str.intern()的执行原理：
        堆 (Heap)
        ┌─────────────────┐
        │ String对象1     │←──┐
        │ value: char[]   │   │
        │ hash: ...       │   │
        └─────────────────┘   │
                 ↑            │
                 │            │
                 │            │
        ┌─────────────────┐   │
        │ char[]数组       │    │
        │ ['Q', 'W']      │   │
        └─────────────────┘   │
                              │
        常量池 (StringTable)   │
        ┌─────────┬─────────┐ │
        |  Key    | Value   | │
        | "Q"     | → ...   | │
        | "W"     | → ...   | │
        | "QW"    | → ──────┘ │
        └─────────┴─────────┘
     */

    /**
     * 任务3：分析以下代码的内存使用情况
     */
    public static void analyzeMemoryUsage() {
        String s1 = "hello";
        String s2 = new String("hello");
        String s3 = s2.intern();

        StringBuilder sb = new StringBuilder();
        StringBuffer sbf = new StringBuffer();

        // 请解释s1, s2, s3, sb, sbf的内存分配情况
    }

    /**
     * 任务4：解释字符串池机制并分析以下代码
     */
    public static void explainStringPool() {
        String a = "java";
        String b = "java";
        String c = new String("java");
        String d = c.intern();

        System.out.println(a == b);
        System.out.println(a == c);
        System.out.println(a == d);
        // 请分析a==b, a==c, a==d的结果及原因
    }
}
